﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
using Microsoft.Data.ConnectionUI;
using MessageBox = System.Windows.MessageBox;

namespace MailSender
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private const string searchPlaceHolder = "Текст для поиска...";
        private Settings _Settings;
        private DispatcherTimer _searchTimer = new DispatcherTimer();
        private Sender _Sender = null;
        private string _currentSettFile = "default.set";

        public MainWindow()
        {
            InitializeComponent();
            List<MailEntity> list = new List<MailEntity>();
            Closing += MainWindow_Closing;

            _searchTimer.IsEnabled = false;
            _searchTimer.Interval = new TimeSpan(0, 0, 0, 500);
            _searchTimer.Tick += _searchTimer_Tick;

            try
            {
                _Settings = Settings.Load("default.set");

            }
            catch (Exception ex)
            {
                if (_Settings == null)
                    _Settings = new Settings();

                MessageBox.Show(this, "Не удалось загрузить файл настроек по умолчанию default.set\r\n" + ex.Message,
                                "Настройки не определены",
                                MessageBoxButton.OK, MessageBoxImage.Error);

            }

            UpdateSettView();
            emailsList.ItemsSource = list;

        }

        void _searchTimer_Tick(object sender, EventArgs e)
        {
            emailsList.Items.Filter += new Predicate<object>(SearchInList);
        }

        private bool SearchInList(object obj)
        {
            var ent = obj as MailEntity;
            string cond = SearchClientEdit.Text;

            if (ent == null)
                return false;

            string s = (ent.Email ?? "") + (ent.Name ?? "");

            return (s.ToLower().Contains(cond));
        }

        void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            if (_Settings != null)
                try
                {
                    SearchClientEdit.Focus();
                    _Settings.Save(_currentSettFile);
                }
                catch (Exception ex)
                {
                    var res = MessageBox.Show(this, "Не удалось сохранить файл настроек default.set\r\n" + ex.Message + "\r\n\r\n" + "Сохранить вручную?",
                                    "Настройки не сохнанены",
                                    MessageBoxButton.YesNo, MessageBoxImage.Error);

                    if (res == MessageBoxResult.Yes)
                    {
                        Save_Click(null, null);

                    }
                }
        }

        private void UpdateSettView()
        {
            DataContext = null;
            DataContext = _Settings;
        }

        private void textBox6_GotFocus(object sender, RoutedEventArgs e)
        {
            if (SearchClientEdit.Text.Equals(searchPlaceHolder))
            {
                SearchClientEdit.Text = "";
                SearchClientEdit.Foreground = new SolidColorBrush(Color.FromArgb(0xff, 0, 0, 0));
            }
        }

        private void SearchClientEdit_LostFocus(object sender, RoutedEventArgs e)
        {
            if (string.IsNullOrWhiteSpace(SearchClientEdit.Text))
            {
                SearchClientEdit.Text = searchPlaceHolder;
                SearchClientEdit.Foreground = new SolidColorBrush(Color.FromArgb(0xb9, 0, 0, 0));

            }
        }

        public void ShowErrorMessage(string caption, string text)
        {
            MessageBox.Show(this, text, caption, MessageBoxButton.OK, MessageBoxImage.Error);
        }

        private void Save_Click(object sender, RoutedEventArgs e)
        {
            SaveFileDialog dlg = new SaveFileDialog();
            dlg.InitialDirectory = System.AppDomain.CurrentDomain.BaseDirectory;

            if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                try
                {
                    _Settings.Save(dlg.FileName);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(this, "Не удалось сохранить файл настроек " + dlg.FileName + "\r\n" + ex.Message,
                                    "Настройки не сохнанены",
                                    MessageBoxButton.OK, MessageBoxImage.Error);
                }

        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                LoadAddressesFromFile(fileName: dlg.FileName);
                UpdateSettView();
            }
        }

        private void LoadAddressesFromFile(string fileName)
        {
            var list = File.ReadAllLines(fileName);
            emailsList.ItemsSource = list.Select(v => new MailEntity { Email = v, Checked = true });
            _Settings.AddressFile = fileName;
        }

        private void button3_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                try
                {
                    _Settings = Settings.Load(dlg.FileName);
                    _currentSettFile = dlg.FileName;
                    UpdateSettView();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(this, "Не удалось загрузить файл настроек " + dlg.FileName + "\r\n" + ex.Message,
                                    "Настройки не загружены",
                                    MessageBoxButton.OK, MessageBoxImage.Error);
                }
        }

        private void button8_Click(object sender, RoutedEventArgs e)
        {
            DataConnectionDialog cnDlg = new DataConnectionDialog();
            cnDlg.DataSources.Add(DataSource.SqlDataSource);
            try
            {
                cnDlg.ConnectionString = connEdit.Text;
            }
            catch { }

            if (DataConnectionDialog.Show(cnDlg) == System.Windows.Forms.DialogResult.OK)
                connEdit.Text = cnDlg.ConnectionString;

        }

        private void SearchClientEdit_KeyUp(object sender, System.Windows.Input.KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
                Search_Click(null, null);
        }

        private void SearchClientEdit_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
        {
        }

        private void Search_Click(object sender, RoutedEventArgs e)
        {
            if (!string.IsNullOrWhiteSpace(SearchClientEdit.Text) && SearchClientEdit.Text != searchPlaceHolder)
                emailsList.Items.Filter = new Predicate<object>(SearchInList);
            else
                emailsList.Items.Filter = null;
        }

        private void button9_Click(object sender, RoutedEventArgs e)
        {
            if (!File.Exists(_Settings.AddressFile))
            {
                ShowErrorMessage("Загрузка адресов", "Файл с адресами отсутствует: " + _Settings.AddressFile);
                return;
            }

            LoadAddressesFromFile(_Settings.AddressFile);
        }

        private void SetCheckedInList(bool val)
        {
            foreach (var item in emailsList.Items)
            {
                var eml = item as MailEntity;
                if (eml != null)
                    eml.Checked = val;
            }

            var list = emailsList.ItemsSource;

            emailsList.ItemsSource = null;
            emailsList.ItemsSource = list;
        }

        private void button5_Click(object sender, RoutedEventArgs e)
        {
            SetCheckedInList(true);
        }

        private void button6_Click(object sender, RoutedEventArgs e)
        {
            SetCheckedInList(false);
        }

        private void button12_Click(object sender, RoutedEventArgs e)
        {
            _Settings.Attache.RemoveAt(AttachList.SelectedIndex);
            RefreshAttache();
        }

        private void RefreshAttache()
        {
            AttachList.ItemsSource = null;
            AttachList.ItemsSource = _Settings.Attache;
        }

        private void button13_Click(object sender, RoutedEventArgs e)
        {
            _Settings.Attache.Clear();
            RefreshAttache();
        }

        private void button11_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Multiselect = true;

            if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                if (dlg.FileNames.Length > 0)
                    _Settings.Attache.AddRange(dlg.FileNames);

                RefreshAttache();
            }

        }

        private void button10_Click(object o, RoutedEventArgs e)
        {
            if (_Sender == null || !_Sender.InProgress)
            {
                var emails = emailsList.Items.Cast<MailEntity>().Where(m => m.Checked);

                if (emails == null || !emails.Any())
                {
                    MessageBox.Show(this, "Отправка невозможна, т.к. не удалось получить список адресов",
                                    "Отправка невозможна",
                                    MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }

                _Sender = new Sender(_Settings, emails.Select(m => m.Email).ToArray());

                _Sender.Send(WriteLog, SetProgress, OnEndOfSending);
                button10.Content = "СТОП!";
            }
            else
            {
                _Sender.Stop();
                //button10.Content = "Отправить";
            }

        }

        protected void SetProgress(int val)
        {
            Dispatcher.Invoke(new Action<int>(param => progressBar1.Value = param), val);
        }

        protected void OnEndOfSending()
        {
            Dispatcher.Invoke(new Action(() => button10.Content = "Отправить"));
        }

        private void WriteLog(string s)
        {
            Dispatcher.Invoke(new Action<string>(param => LogList.Items.Add(DateTime.Now.ToString("HH:mm:ss.fff ->") + param)), s);
        }

    }
}
